/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 *
 */

import { CoreTask, DurationEvent, globalData, MetricLogType, SubmitOption, TaskState } from '@ohos/hvigor';
import { WorkerPoolDelegator } from '@ohos/hvigor';
import { ProjectConfig } from '@ohos/hvigor-arkts-compose';
import { Level } from 'log4js';
import path from 'path';

import { OhosLogger } from '../../utils/log/ohos-logger.js';

import { CopyWorker } from './copy-worker.js';
import { run, runArkLint } from './job.js';

/**
 * 向线程池提交执行编译ArkTS的任务
 *
 * @param task task
 * @param workerPool 线程池
 * @param logger 日志
 * @param config 编译参数
 * @param callback 编译后的回调函数，其入参是work的返回值
 * @param targetWorkers 目标worker
 */
export async function submitArkCompileWork(
  task: CoreTask,
  workerPool: WorkerPoolDelegator,
  logger: OhosLogger,
  config: ProjectConfig,
  callback: Function,
  targetWorkers?: number[],
): Promise<string | null> {
  config.level = logger.getLevel() as Level;
  config.projectPath = config.aceModuleRoot;
  config.buildId = globalData.buildId;

  const tcb = workerPool.submit(task, path.resolve(__dirname, './job.js/run'), {
    workInput: config,
    callback: callback,
    targetWorkers: targetWorkers,
    useReturnVal: true,
    hasSideEffects: false,
    preludeDeps: ['@ohos/hvigor'],
    memorySensitive: true,
  });

  if (tcb.getState() === TaskState.REJECT) {
    logger.debug('Worker dispatch failed, running ark compile on main thread.');
    config.isMainThread = true;
    await run(config).then((returnVal) => {
      if (returnVal instanceof Error) {
        throw returnVal;
      } else {
        callback(returnVal);
      }
    });
  }

  // 向线程池提交拷贝静态资源的任务
  // 新增逻辑copyCodeResourceEnable为false的场景下跳过复制动作
  if (!config.isFaMode && !config.widgetCompile && config.copyCodeResourceEnable) {
    await CopyWorker.submitCopyResourcesWork(task, workerPool, logger, config, () => {
      logger.debug(`CopyResources is end, endTime: ${process.hrtime.bigint()}`);
    });
  }

  return tcb.getState() === TaskState.REJECT ? null : tcb.getId();
}

export async function submitArkLintWork(
  task: CoreTask,
  workerPool: WorkerPoolDelegator,
  logger: OhosLogger,
  config: ProjectConfig,
  entry: Record<string, unknown>,
  subDurationEvent: DurationEvent,
): Promise<void> {
  config.level = logger.getLevel() as Level;
  config.projectPath = config.aceModuleRoot;
  const script: string = path.resolve(__dirname, './job.js/runArkLint');
  const options: SubmitOption = { workInput: { config, entry }, hasSideEffects: false };
  if (workerPool.submit(task, script, options).getState() === TaskState.REJECT) {
    const executeTaskName = 'perform ark linter';
    const subExecuteDurationEvent = subDurationEvent.createSubEvent(executeTaskName, '');
    subExecuteDurationEvent.start();
    logger.debug('Worker dispatch failed, running ark lint on main thread.');
    config.isMainThread = true;
    await runArkLint({ config, entry });
    subExecuteDurationEvent.stop();
    subExecuteDurationEvent.setLog(executeTaskName, MetricLogType.INFO);
  }
}
